package cn.bonoon.kernel.security;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import cn.bonoon.kernel.menus.ChannelDefinition;
import cn.bonoon.kernel.menus.ItemableDefinition;
import cn.bonoon.kernel.menus.MenuDefinition;
import cn.bonoon.kernel.menus.MenuableDefinition;
import cn.bonoon.kernel.menus.ModuleDefinition;
import cn.bonoon.kernel.menus.ModuleManager;
import cn.bonoon.kernel.menus.TabItemDefinition;
import cn.bonoon.kernel.menus.TabsDefinition;
import cn.bonoon.kernel.menus.privileges.PrivilegeInspector;

/**
 * 用来缓存已经登录的用户的权限信息
 * @author jackson
 *
 */
public class LogonUserPrivilegeMapped {
	
	private final ModuleManager moduleManager;
	
	private final Map<String, LogonUserPrivilegeItem> items = new HashMap<>();
	/** 所有当前用户可以访问的子系统 */
	private final Set<String> modules = new HashSet<>();
	/** 所有当前用户可访问的频道；但如果这个频道本身是有功能的，则该用户不一定能访问上面的功能 */
	private final Set<String> channels = new HashSet<>();
	
	/** 系统默认的模块，也就是说系统登录成功后默认进入的子系统 */
	private ModuleDefinition defaultModule;
	
	class LogonUserPrivilegeItem{
		final String id;
		String name;
		long action;
		LogonUserPrivilegeItem(String id){
			this.id = id;
		}
		

		LogonUserPrivilegeItem(String id, String name){
			this(id);
			this.name = name;
		}
		
	}
	
	private void internalAdd(String id, String name){
		
		ItemableDefinition it = moduleManager.find(id);
		
		if(it == null) return;
		
		if(null == defaultModule) defaultModule = it.getModule();
		
		modules.add(it.getModule().getId());
		channels.add(it.getChannel().getId());
		
		items.put(it.getId(), new LogonUserPrivilegeItem(it.getId(), name));
	}
	
	/** 注意：id不能加密 */
	public void add(String id, String name){
		internalAdd(id, name);
	}
	
	public LogonUserPrivilegeMapped(ModuleManager moduleManager){
		this.moduleManager = moduleManager;
	}

	public List<Long> getActions(MenuableDefinition item) {
		return Collections.emptyList();
	}
	
	private final PrivilegeInspector privilege = new PrivilegeInspector() {
			
			@Override
			public boolean hasPrivilege(ChannelDefinition item) {
				return channels.contains(item.getId());
			}
			
			@Override
			public boolean hasPrivilege(TabItemDefinition item) {
				return items.containsKey(item.getId());
			}
			
			@Override
			public boolean hasPrivilege(TabsDefinition item) {
				return items.containsKey(item.getId());
			}
			
			@Override
			public boolean hasPrivilege(MenuableDefinition item) {
				return items.containsKey(item.getId()) || channels.contains(item.getId());
			}
			
			@Override
			public boolean hasPrivilege(MenuDefinition item) {
				return items.containsKey(item.getId());
			}
		};

	public PrivilegeInspector privilege(MenuableDefinition item) {
		return privilege;
	}

	public PrivilegeInspector privilege(ModuleDefinition module) {
		return privilege;
	}

	public PrivilegeInspector privilege(TabsDefinition tab) {
		return privilege;
	}

	public PrivilegeInspector privilege(String mid, String cid) {
		return privilege;
	}

	public ModuleDefinition getDefaultModule() {
		return defaultModule;
	}
}
